package io.renren.common.aspect;

import com.alibaba.fastjson2.JSON;
import io.renren.common.utils.HttpContextUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Aspect
@Component
public class HandlerAroundAspect {

    private final static Logger LOGGER = LoggerFactory.getLogger(HandlerAroundAspect.class);

    @Pointcut("execution(* *..*.controller.*Controller.*(..))")
    public void requestMappingPointCut() {
    }


    @Around("requestMappingPointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        // 计算请求时长
        long startTime = System.currentTimeMillis();
        Signature signature = joinPoint.getSignature();
        Object[] args = joinPoint.getArgs();
        String methodLocal = signature.getDeclaringType().getSimpleName() + "." + signature.getName();
        LOGGER.info("================================methodLocal start:{}====================================",methodLocal);
        //过滤无法序列化
        Stream<?> stream = args !=null  ? Stream.empty() : Arrays.stream(args);
        List<Object> logArgs = stream
                .filter(arg -> (!(arg instanceof HttpServletRequest) && !(arg instanceof HttpServletResponse)))
                .collect(Collectors.toList());
        LOGGER.info("request：{}", JSON.toJSONString(logArgs));
        LOGGER.info("requestUrl：{}", HttpContextUtils.getHttpServletRequest().getRequestURI());
        Object response = joinPoint.proceed(args);
        LOGGER.info("response：{}", JSON.toJSONString(response));
        long endTime = System.currentTimeMillis();
        LOGGER.info("================================methodLocal end:{} time:{}=====================================",methodLocal,endTime - startTime);
        return response;
    }

}
